import * as vscode from 'vscode';
import * as bent from 'bent';
const url = 'https://gitee.com/api/v5';

const get = bent(url, 'json', 'GET', 200);
const post = bent(url, 'json', 'POST', 200, 201);
const del = bent(url, 'DELETE', 204);

export interface Project {
  /** 仓库名称 */
  full_name: string;
  /** 项目地址 */
  url: string;
  /** clone地址 */
  ssh_url: string;
  /** 项目名称 */
  name: string;
  /** 是否私有 */
  private: boolean;
  /** 是否公开 */
  public: boolean;
  /** 地址 */
  path: string;
  owner: {
    /** 登录名 */
    login: string;
  },
  /** 项目描述 */
  description: string;
}

export interface Branches {
  /** 分支名称 */
  name: string;
}

export interface GistFile {
  filename?: string;
  raw_url?: string;
  content: string;
}

export interface GistFiles {
  [fileName: string]: GistFile;
}

export interface Gist {
  id: string;
  owner: string;
  description: string;
  public: boolean;
  files: GistFiles;
}

export class GiteeApi {
  /**
   * 获取所有的仓库
   * @param page 页码
   * @param limit 每页个数
   */
  public async getProjectList(page: number, limit: number): Promise<Project[]> {
    const list = await get('/user/repos?' + queryToStr({
      access_token: this.accessToken,
      visibility: 'all',
      sort: 'full_name',
      page: page,
      per_page: limit,
    })) as Project[] || [];
    return list;
  }

  /**
   * 获取仓库的所有分支
   * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
   * @param repo 仓库路径
   */
  public async getAllBranches(owner: string, repo: string): Promise<Branches[]> {
    return (await get(`/repos/${ owner }/${ repo }/branches?access_token=${ this.accessToken }`)) as Branches[];
  }

  /**
   * 创建仓库
   * @param name 仓库名称
   * @param isPrivate 是否私有
   * @param description 仓库描述
   */
  public async createProject(name: string, isPrivate: boolean, description: string = ''): Promise<Project> {
    const result = await post('/user/repos', {
      access_token: this.accessToken,
      name,
      description,
      private: isPrivate
    }) as Project;
    return result;
  }

  /**
   * 删除仓库
   * @param owner 仓库所属空间地址(企业、组织或个人的地址path)
   * @param repo 仓库路径
   */
  public async deleteProject(owner: string, repo: string) {
    await del(`/repos/${ owner }/${ repo }?access_token=${ this.accessToken }`);
  }

  /**
   * 
   * @param page 页码
   * @param limit 每页个数
   */
  public async getGistList(page: number, limit: number): Promise<Gist[]> {
    const list = await get(`/gists?access_token=${ this.accessToken }&page=${ page }&per_page=${ limit }`) as Gist[];
    return list;
  }

  private get accessToken() {
    return vscode.workspace.getConfiguration('gitee').get<string>('accessToken') || '';
  }
}

function queryToStr(query: Object) {
  const list = [];
  for (const [key, value] of Object.entries(query)) {
    list.push(`${ key }=${ value }`);
  }
  return list.join('&');
}
